package com.zhy.baselibrary.view.banner

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.blankj.utilcode.util.SizeUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.zhy.baselibrary.R
import com.zhy.baselibrary.view.RoundImageView

class BannerFly @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {
    private var mPointRealContainerLl: LinearLayout? = null
    private var mViewPager: ViewPager? = null

    //本地图片资源
    private var mImages = ArrayList<BannerBean>()

    //网络图片资源
    private var mImageUrls = ArrayList<BannerBean>()

    //是否是网络图片
    private var mIsImageUrl = false

    //是否只有一张图片
    private var mIsOneImg = false

    //是否可以自动播放
    private val mAutoPlayAble = true

    //是否正在播放
    private var mIsAutoPlaying = false

    //自动播放时间
    private val mAutoPalyTime = 4000

    //当前页面位置
    private var mCurrentPositon = 0

    //指示点位置
    private var mPointPosition = CENTER

    //指示点资源
    private val mPointDrawableResId = R.drawable.selector_banner_point

    //指示容器背景
    private var mPointContainerBackgroundDrawable: Drawable? = null

    //指示容器布局规则
    private var mPointRealContainerLp: LayoutParams? = null
    //指示点是否可见
    private var mPointsIsVisible = true
    private var type = 0
    private val mAutoPlayHandler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            mCurrentPositon++
            mViewPager!!.currentItem = mCurrentPositon
            sendEmptyMessageDelayed(WHAT_AUTO_PLAY, mAutoPalyTime.toLong())
        }
    }
    private var length = 0
    private var flag = true
    private fun init(context: Context, attrs: AttributeSet?) {
        val a = context.obtainStyledAttributes(attrs, R.styleable.FlyBanner)
        mPointsIsVisible = a.getBoolean(R.styleable.FlyBanner_points_visibility, true)
        mPointPosition = a.getInt(R.styleable.FlyBanner_points_position, CENTER)
        mPointContainerBackgroundDrawable =
            a.getDrawable(R.styleable.FlyBanner_points_container_background)
        a.recycle()
        setLayout(context)
    }

    fun setLayout(context: Context?) {
        //关闭view的OverScroll
        overScrollMode = View.OVER_SCROLL_NEVER
        //设置指示器背景
        if (mPointContainerBackgroundDrawable == null) {
            mPointContainerBackgroundDrawable = ColorDrawable(Color.parseColor("#00aaaaaa"))
        }
        //添加ViewPager
        mViewPager = ViewPager(context!!)
        addView(mViewPager, LayoutParams(RMP, RMP))
        //设置指示器背景容器
        val pointContainerRl = RelativeLayout(context)
        if (Build.VERSION.SDK_INT >= 16) {
            pointContainerRl.background = mPointContainerBackgroundDrawable
        } else {
            pointContainerRl.setBackgroundDrawable(mPointContainerBackgroundDrawable)
        }
        //设置内边距
        pointContainerRl.setPadding(0, 20, 0, SizeUtils.dp2px(5f))

        //设定指示器容器布局及位置
        val pointContainerLp = LayoutParams(RMP, RWP)
        pointContainerLp.addRule(ALIGN_PARENT_BOTTOM)
        addView(pointContainerRl, pointContainerLp)
        //设置指示器容器
        mPointRealContainerLl = LinearLayout(context)
        mPointRealContainerLl!!.orientation = LinearLayout.HORIZONTAL
        mPointRealContainerLp = LayoutParams(RWP, RWP)
        pointContainerRl.addView(mPointRealContainerLl, mPointRealContainerLp)
        //设置指示器容器是否可见
        if (mPointRealContainerLl != null) {
            if (mPointsIsVisible) {
                mPointRealContainerLl!!.visibility = View.VISIBLE
            } else {
                mPointRealContainerLl!!.visibility = View.GONE
            }
        }
        //设置指示器布局位置
        if (mPointPosition == CENTER) {
            mPointRealContainerLp!!.addRule(CENTER_HORIZONTAL)
        } else if (mPointPosition == LEFT) {
            mPointRealContainerLp!!.addRule(ALIGN_PARENT_LEFT)
        } else if (mPointPosition == RIGHT) {
            mPointRealContainerLp!!.addRule(ALIGN_PARENT_RIGHT)
        }
    }

    /**
     * 设置本地图片
     *
     * @param images
     */
    fun <T :BannerBean> setImages(images: List<T>) {
        //加载本地图片
        mIsImageUrl = false
        mImages.clear()
        mImages.addAll(images)
        if (images.size <= 1) mIsOneImg = true
        //初始化ViewPager
        initViewPager()
    }

    /**
     * 设置网络图片
     *
     * @param urls
     */
    fun  <T :BannerBean>  setImagesUrl(urls: List<T>) {
        //加载网络图片
        mIsImageUrl = true
        mImageUrls.clear()
        mImageUrls.addAll(urls)
        if (urls.size <= 1) mIsOneImg = true
        //初始化ViewPager
        initViewPager()
    }

    /**
     * 设置指示点是否可见
     *
     * @param isVisible
     */
    fun setPointsIsVisible(isVisible: Boolean) {
        if (mPointRealContainerLl != null) {
            if (isVisible) {
                mPointRealContainerLl!!.visibility = View.VISIBLE
            } else {
                mPointRealContainerLl!!.visibility = View.GONE
            }
        }
    }

    /**
     * 对应三个位置 CENTER,RIGHT,LEFT
     *
     * @param position
     */
    fun setPoinstPosition(position: Int) {
        //设置指示器布局位置
        if (position == CENTER) {
            mPointRealContainerLp!!.addRule(CENTER_HORIZONTAL)
        } else if (position == LEFT) {
            mPointRealContainerLp!!.addRule(ALIGN_PARENT_LEFT)
        } else if (position == RIGHT) {
            mPointRealContainerLp!!.addRule(ALIGN_PARENT_RIGHT)
        }
    }

    private fun initViewPager() {
        //当图片多于1张时添加指示点
        if (!mIsOneImg) {
            addPoints()
        }
        //设置ViewPager
        val adapter = FlyPageAdapter()
        mViewPager?.adapter = adapter
        mViewPager?.addOnPageChangeListener(mOnPageChangeListener)
        //跳转到首页
        mViewPager!!.setCurrentItem(1, false)
        //当图片多于1张时开始轮播
        if (!mIsOneImg && flag) {
            startAutoPlay()
        }
    }

    /**
     * 返回真实的位置
     *
     * @param position
     * @return
     */
    private fun toRealPosition(position: Int): Int {
        var realPosition: Int
        if (mIsImageUrl) {
            realPosition = (position - 1) % mImageUrls.size
            if (realPosition < 0) realPosition += mImageUrls.size
        } else {
            realPosition = (position - 1) % mImages.size
            if (realPosition < 0) realPosition += mImages.size
        }
        return realPosition
    }

    private val mOnPageChangeListener: ViewPager.OnPageChangeListener =
        object : ViewPager.OnPageChangeListener {
            override fun onPageScrolled(
                position: Int, positionOffset: Float,
                positionOffsetPixels: Int
            ) {
            }

            override fun onPageSelected(position: Int) {
                mCurrentPositon = if (mIsImageUrl) {
                    position % (mImageUrls.size + 2)
                } else {
                    position % (mImages.size + 2)
                }
                switchToPoint(toRealPosition(mCurrentPositon), type)
                onItemChangeListener?.onItemChange(mCurrentPositon)
            }

            override fun onPageScrollStateChanged(state: Int) {
                if (state == ViewPager.SCROLL_STATE_IDLE) {
                    val current = mViewPager?.currentItem
                    val lastReal = (mViewPager?.adapter?.count?:0) - 2
                    if (current == 0) {
                        mViewPager!!.setCurrentItem(lastReal, false)
                    } else if (current == lastReal + 1) {
                        mViewPager!!.setCurrentItem(1, false)
                    }
                }
            }
        }

    private inner class FlyPageAdapter : PagerAdapter() {
        override fun getCount(): Int {
            //当只有一张图片时返回1
            if (mIsOneImg) {
                return 1
            }
            //当为网络图片，返回网页图片长度
            return if (mIsImageUrl) mImageUrls.size + 2 else mImages.size + 2
            //当为本地图片，返回本地图片长度
        }

        override fun isViewFromObject(view: View, `object`: Any): Boolean {
            return view === `object`
        }

        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            val imageView = ImageView(context)
//            imageView.setType(RoundImageView.TYPE_ROUND)
//            imageView.setCornerRadius(10)
            imageView.scaleType = ImageView.ScaleType.FIT_XY
            if (mIsImageUrl) {
                val index = toRealPosition(position)
                val img = mImageUrls[index]
                Glide.with(context).load(img.imageUrl)
                    .skipMemoryCache(false)
                    .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                    .into(imageView)
                imageView.setOnClickListener {
                    val item = mImageUrls[toRealPosition(position)]
                    mOnItemClickListener?.onItemClick(item)
                }
            } else {
                val index = toRealPosition(position)
                val img = mImages[index]
                imageView.setOnClickListener {
                    val item = mImages[toRealPosition(position)]
                    mOnItemClickListener?.onItemClick(item)
                }
            }
            container.addView(imageView)
            return imageView
        }

        override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
            var `object`: Any? = `object`
            container.removeView(`object` as View?)
            if (`object` != null) `object` = null
        }
    }

    /**
     * 添加指示点
     */
    private fun addPoints() {
        mPointRealContainerLl!!.removeAllViews()
        val lp = LinearLayout.LayoutParams(LWC, LWC)
        lp.setMargins(10, 10, 10, 10)
        var imageView: ImageView
        length = if (mIsImageUrl) mImageUrls.size else mImages.size
        for (i in 0 until length) {
            imageView = ImageView(context)
            imageView.layoutParams = lp
            imageView.setImageResource(mPointDrawableResId)
            mPointRealContainerLl!!.addView(imageView)
        }
        switchToPoint(0, type)
    }

    /**
     * 切换指示器
     *
     * @param type
     * @param currentPoint
     */
    private fun switchToPoint(currentPoint: Int, type: Int) {
        this.type = type
        if (type == 1) {
            val lp = LinearLayout.LayoutParams(LWC, LWC)
            lp.setMargins(10, 10, 10, 10)
            val textView = TextView(context)
            textView.layoutParams = lp
            textView.text = "${currentPoint + 1}/$length"
            mPointRealContainerLl!!.removeAllViews()
            mPointRealContainerLl!!.addView(textView)
        } else {
            for (i in 0 until mPointRealContainerLl!!.childCount) {
                mPointRealContainerLl!!.getChildAt(i).isEnabled = false
            }
            mPointRealContainerLl!!.getChildAt(currentPoint).isEnabled = true
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (mAutoPlayAble && !mIsOneImg) {
            when (ev.action) {
                MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_OUTSIDE -> if (flag) {
                    startAutoPlay()
                }
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    fun setPlay(flag: Boolean) {
        this.flag = flag
    }

    /**
     * 开始播放
     */
    fun startAutoPlay() {
        if (mAutoPlayAble && !mIsAutoPlaying) {
            mIsAutoPlaying = true
            mAutoPlayHandler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, mAutoPalyTime.toLong())
        }
    }

    /**
     * 停止播放
     */
    fun stopAutoPlay() {
        if (mAutoPlayAble && mIsAutoPlaying) {
            mIsAutoPlaying = false
            mAutoPlayHandler.removeMessages(WHAT_AUTO_PLAY)
        }
    }

    private var mOnItemClickListener: OnItemClickListener? = null
    fun setOnItemClickListener(listener: OnItemClickListener) {
        mOnItemClickListener = listener
    }

    interface OnItemClickListener {
        fun onItemClick(item: BannerBean)
    }

    interface OnItemChangeListener {
        fun onItemChange(position: Int)
    }

    private var onItemChangeListener: OnItemChangeListener? = null
    fun setOnItemChangeListener(onItemChangeListener: OnItemChangeListener?) {
        this.onItemChangeListener = onItemChangeListener
    }

    companion object {
        private const val RMP = LayoutParams.MATCH_PARENT
        private const val RWP = LayoutParams.WRAP_CONTENT
        private const val LWC = LinearLayout.LayoutParams.WRAP_CONTENT
        private const val WHAT_AUTO_PLAY = 1000

        //Point位置
        const val CENTER = 0
        const val LEFT = 1
        const val RIGHT = 2
    }

    init {
        init(context, attrs)
    }
}